package com.spring.lo.framework.util;

import com.spring.lo.framework.factory.config.BeanDefinition;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 反射工具
 * @author zhangbh
 * 2023-05-28 22:05
 **/
public class ReflectionUtils {

    /**
     * 创建实例
     * @param clazz 类型
     * @return 类
     */
    public static Object createInstance(Class<?> clazz) {
        Object bean;
        try {
            bean = clazz.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            throw new RuntimeException("创建bean实例异常", e);
        }
        return bean;
    }

    /**
     * 获取字段类型
     * @param clazz 类型
     * @param name 字段名
     * @return 字段实际类型
     */
    public static Class<?> getFieldType(Class<?> clazz, String name) {
        Class<?> fieldType;
        try {
            Field field = clazz.getDeclaredField(name);
            field.setAccessible(true);
            fieldType = field.getType();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
            System.out.printf("加载属性%s错误%n", name);
            return null;
        }
        return fieldType;
    }

    /**
     * 设置字段值
     * @param o 类
     * @param clazz 类型
     * @param fieldName 字段名
     * @param value 字段值
     */
    public static void setFieldValue(Object o, Class<?> clazz, String fieldName, Object value) {
        try {
            Field field = clazz.getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(o, value);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException("获取字段异常", e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("设置字段异常", e);
        }
    }

    /**
     * 获取到实际类型
     * @param className 全路径名称
     * @return class 实际类型
     */
    public static Class<?> resolveClassType(String className) {
        try {
            return Class.forName(className);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 调用类方法
     * @param clazz 类型
     * @param bean 类型对应的类对象
     * @param methodName 触发的方法名
     */
    public static void invokeMethod(Class<?> clazz, Object bean, String methodName) {
        try {
            Method method = clazz.getMethod(methodName);
            // 暴力破解
            method.setAccessible(true);
            method.invoke(bean);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException("获取初始化方法异常", e);
        } catch (InvocationTargetException | IllegalAccessException e) {
            throw new RuntimeException("初始化方法执行异常", e);
        }
    }

}
